package models

import (
	"gorm.io/datatypes"
	"gorm.io/gorm"
)

// Product 商品表
type Product struct {
	BaseModel
	CategoryID    uint           `gorm:"not null;index;comment:分类ID" json:"category_id"`
	Name          string         `gorm:"size:100;not null;comment:商品名称" json:"name"`
	Subtitle      *string        `gorm:"size:200;comment:副标题" json:"subtitle,omitempty"`
	Price         float64        `gorm:"type:decimal(10,2);not null;comment:售价" json:"price"`
	OriginalPrice *float64       `gorm:"type:decimal(10,2);comment:原价" json:"original_price,omitempty"`
	CostPrice     *float64       `gorm:"type:decimal(10,2);comment:成本价" json:"cost_price,omitempty"`
	Stock         int            `gorm:"default:0;comment:库存" json:"stock"`
	SoldCount     int            `gorm:"default:0;comment:已售数量" json:"sold_count"`
	MainImage     string         `gorm:"size:255;not null;comment:主图URL" json:"main_image"`
	DetailImages  datatypes.JSON `gorm:"type:json;comment:详情图URL数组" json:"detail_images"`
	SpecTemplate  datatypes.JSON `gorm:"type:json;comment:规格模板" json:"spec_template"`
	Description   *string        `gorm:"type:text;comment:商品详情" json:"description,omitempty"`
	Status        string         `gorm:"type:enum('draft','on_sale','off_sale');default:'draft';comment:状态" json:"status"`

	// 关联关系
	Category ProductCategory `gorm:"foreignKey:CategoryID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"category,omitempty"`
	Specs    []ProductSpec   `gorm:"foreignKey:ProductID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"specs,omitempty"`
}

func (p *Product) FindByRawSQL(db *gorm.DB, query string, args ...interface{}) error {
	//TODO implement me
	panic("implement me")
}

// 以下方法均实现ModelCRUD接口（与User类似，根据自身字段调整）
func (p *Product) Create(db *gorm.DB) error {
	return db.Create(p).Error
}

func (p *Product) Update(db *gorm.DB) error {
	return db.Model(p).Updates(p).Error
}

func (p *Product) Delete(db *gorm.DB, id uint) error {
	return db.Delete(&Product{}, id).Error
}

func (p *Product) GetByID(db *gorm.DB, id uint) error {
	return db.First(p, id).Error
}

func (p *Product) GetByField(db *gorm.DB, field string, value interface{}) error {
	result := db.Where(map[string]interface{}{field: value}).First(p)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

func (p *Product) List(db *gorm.DB, page, pageSize int) ([]interface{}, int64, error) {
	var total int64
	var products []Product

	if err := db.Model(&Product{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	offset := (page - 1) * pageSize
	if err := db.Offset(offset).Limit(pageSize).Find(&products).Error; err != nil {
		return nil, 0, err
	}

	result := make([]interface{}, len(products))
	for i, v := range products {
		result[i] = v
	}
	return result, total, nil
}

// ProductCategory 商品分类表
type ProductCategory struct {
	BaseModel
	Name      string  `gorm:"size:50;not null;comment:分类名称" json:"name"`
	ParentID  *uint64 `gorm:"index;comment:父分类ID" json:"parent_id,omitempty"`
	Level     int8    `gorm:"default:1;comment:层级(1-一级,2-二级)" json:"level"`
	Sort      int     `gorm:"default:0;comment:排序权重" json:"sort"`
	Icon      *string `gorm:"size:255;comment:图标URL" json:"icon,omitempty"`
	IsVisible bool    `gorm:"default:true;comment:是否显示" json:"is_visible"`

	// 关联关系
	Parent   *ProductCategory  `gorm:"foreignKey:ParentID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"`
	Children []ProductCategory `gorm:"foreignKey:ParentID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"children,omitempty"`
	Products []Product         `gorm:"foreignKey:CategoryID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"`
}

func (pc *ProductCategory) FindByRawSQL(db *gorm.DB, query string, args ...interface{}) error {
	//TODO implement me
	panic("implement me")
}

func (pc *ProductCategory) GetByField(db *gorm.DB, field string, value interface{}) error {
	result := db.Where(map[string]interface{}{field: value}).First(pc)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

// ProductCategory 商品分类 CRUD 实现
func (pc *ProductCategory) Create(db *gorm.DB) error {
	// 校验层级：父分类存在时，子分类层级=父分类层级+1
	if pc.ParentID != nil {
		var parentCat ProductCategory
		if err := db.First(&parentCat, *pc.ParentID).Error; err != nil {
			return err
		}
		pc.Level = parentCat.Level + 1
	}
	return db.Create(pc).Error
}

func (pc *ProductCategory) Update(db *gorm.DB) error {
	// 支持更新名称、排序、图标、显示状态，禁止直接修改层级（需通过父分类间接修改）
	return db.Model(pc).Updates(map[string]interface{}{
		"name":       pc.Name,
		"parent_id":  pc.ParentID,
		"sort":       pc.Sort,
		"icon":       pc.Icon,
		"is_visible": pc.IsVisible,
	}).Error
}

func (pc *ProductCategory) Delete(db *gorm.DB, id uint) error {
	// 级联删除子分类（若有）
	return db.Transaction(func(tx *gorm.DB) error {
		if err := tx.Where("parent_id = ?", id).Delete(&ProductCategory{}).Error; err != nil {
			return err
		}
		return tx.Delete(&ProductCategory{}, id).Error
	})
}

func (pc *ProductCategory) GetByID(db *gorm.DB, id uint) error {
	// 预加载子分类（树形结构查询）
	return db.Preload("Children").First(pc, id).Error
}

func (pc *ProductCategory) List(db *gorm.DB, page, pageSize int) ([]interface{}, int64, error) {
	var total int64
	var categories []ProductCategory

	// 支持按层级、父分类ID、显示状态筛选
	query := db.Model(&ProductCategory{})
	if pc.Level > 0 {
		query = query.Where("level = ?", pc.Level)
	}
	if pc.ParentID != nil {
		query = query.Where("parent_id = ?", *pc.ParentID)
	}
	if pc.IsVisible {
		query = query.Where("is_visible = ?", pc.IsVisible)
	}

	// 按排序权重倒序
	query = query.Order("sort DESC")

	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	offset := (page - 1) * pageSize
	if err := query.Offset(offset).Limit(pageSize).Preload("Children").Find(&categories).Error; err != nil {
		return nil, 0, err
	}

	result := make([]interface{}, len(categories))
	for i, v := range categories {
		result[i] = v
	}
	return result, total, nil
}

// ProductSpec 商品规格表
type ProductSpec struct {
	BaseModel
	ProductID uint64         `gorm:"not null;index;comment:商品ID" json:"product_id"`
	Name      string         `gorm:"size:50;not null;comment:规格名称" json:"name"`
	Values    datatypes.JSON `gorm:"type:json;not null;comment:规格值" json:"values"`

	// 关联关系
	Product Product `gorm:"foreignKey:ProductID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"`
}

func (ps *ProductSpec) FindByRawSQL(db *gorm.DB, query string, args ...interface{}) error {
	//TODO implement me
	panic("implement me")
}

func (ps *ProductSpec) GetByField(db *gorm.DB, field string, value interface{}) error {
	result := db.Where(map[string]interface{}{field: value}).First(ps)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

// ProductSpec 商品规格 CRUD 实现
func (ps *ProductSpec) Create(db *gorm.DB) error {
	return db.Create(ps).Error
}

func (ps *ProductSpec) Update(db *gorm.DB) error {
	return db.Model(ps).Updates(map[string]interface{}{
		"name":   ps.Name,
		"values": ps.Values,
	}).Error
}

func (ps *ProductSpec) Delete(db *gorm.DB, id uint) error {
	return db.Delete(&ProductSpec{}, id).Error
}

func (ps *ProductSpec) GetByID(db *gorm.DB, id uint) error {
	return db.First(ps, id).Error
}

func (ps *ProductSpec) List(db *gorm.DB, page, pageSize int) ([]interface{}, int64, error) {
	var total int64
	var specs []ProductSpec

	// 必按商品ID筛选（规格属于商品）
	query := db.Model(&ProductSpec{}).Where("product_id = ?", ps.ProductID)

	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	offset := (page - 1) * pageSize
	if err := query.Offset(offset).Limit(pageSize).Find(&specs).Error; err != nil {
		return nil, 0, err
	}

	result := make([]interface{}, len(specs))
	for i, v := range specs {
		result[i] = v
	}
	return result, total, nil
}
